package handler

import (
	"fitness/go-admin/internal/model"
	"fitness/go-admin/internal/service"
	"fitness/go-admin/pkg/errcode"
	"fitness/go-admin/pkg/response"
	"strconv"

	"github.com/gin-gonic/gin"
)

type BookingHandler struct {
	service service.BookingService
}

func NewBookingHandler(service service.BookingService) *BookingHandler {
	return &BookingHandler{service: service}
}

// Create 创建预约
func (h *BookingHandler) Create(c *gin.Context) {
	var req model.BookingCreateReq
	if err := c.ShouldBindJSON(&req); err != nil {
		response.Error(c, 400, "参数错误: "+err.Error())
		return
	}

	userID := c.GetUint("userID")

	result, err := h.service.Create(userID, &req)
	if err != nil {
		if bizErr, ok := err.(*errcode.BusinessError); ok {
			response.ErrorWithBusiness(c, bizErr)
			return
		}
		response.Error(c, 500, err.Error())
		return
	}

	response.Success(c, result, "预约成功")
}

// Cancel 取消预约
func (h *BookingHandler) Cancel(c *gin.Context) {
	bookingID, err := strconv.ParseUint(c.Param("id"), 10, 32)
	if err != nil {
		response.Error(c, 400, "预约ID格式错误")
		return
	}

	var req model.BookingCancelReq
	_ = c.ShouldBindJSON(&req) // 取消原因可选

	userID := c.GetUint("userID")

	if err := h.service.Cancel(userID, uint(bookingID), &req); err != nil {
		if bizErr, ok := err.(*errcode.BusinessError); ok {
			response.ErrorWithBusiness(c, bizErr)
			return
		}
		response.Error(c, 500, err.Error())
		return
	}

	response.Success(c, nil, "取消成功")
}

// MyBookings 我的预约列表
func (h *BookingHandler) MyBookings(c *gin.Context) {
	var req model.BookingListReq
	if err := c.ShouldBindQuery(&req); err != nil {
		response.Error(c, 400, "参数错误: "+err.Error())
		return
	}

	userID := c.GetUint("userID")

	items, total, err := h.service.MyBookings(userID, &req)
	if err != nil {
		response.Error(c, 500, err.Error())
		return
	}

	page := req.Page
	if page < 1 {
		page = 1
	}
	pageSize := req.PageSize
	if pageSize < 1 {
		pageSize = 10
	}

	response.SuccessWithPage(c, items, total, page, pageSize, "获取成功")
}

// Get 获取预约详情
func (h *BookingHandler) Get(c *gin.Context) {
	bookingID, err := strconv.ParseUint(c.Param("id"), 10, 32)
	if err != nil {
		response.Error(c, 400, "预约ID格式错误")
		return
	}

	userID := c.GetUint("userID")
	role, _ := c.Get("role")
	isAdmin := role == "admin"

	detail, err := h.service.GetByID(userID, uint(bookingID), isAdmin)
	if err != nil {
		if bizErr, ok := err.(*errcode.BusinessError); ok {
			response.ErrorWithBusiness(c, bizErr)
			return
		}
		response.Error(c, 500, err.Error())
		return
	}

	response.Success(c, detail, "获取成功")
}

// CheckIn 课程签到
func (h *BookingHandler) CheckIn(c *gin.Context) {
	bookingID, err := strconv.ParseUint(c.Param("id"), 10, 32)
	if err != nil {
		response.Error(c, 400, "预约ID格式错误")
		return
	}

	userID := c.GetUint("userID")
	role, _ := c.Get("role")
	isAdmin := role == "admin"

	result, err := h.service.CheckIn(userID, uint(bookingID), isAdmin)
	if err != nil {
		if bizErr, ok := err.(*errcode.BusinessError); ok {
			response.ErrorWithBusiness(c, bizErr)
			return
		}
		response.Error(c, 500, err.Error())
		return
	}

	response.Success(c, result, "签到成功")
}

// ListByCourse 获取课程的预约列表
func (h *BookingHandler) ListByCourse(c *gin.Context) {
	courseID, err := strconv.ParseUint(c.Param("id"), 10, 32)
	if err != nil {
		response.Error(c, 400, "课程ID格式错误")
		return
	}

	var req model.BookingListReq
	if err := c.ShouldBindQuery(&req); err != nil {
		response.Error(c, 400, "参数错误: "+err.Error())
		return
	}

	userID := c.GetUint("userID")
	role, _ := c.Get("role")
	isAdmin := role == "admin"

	items, total, err := h.service.ListByCourse(uint(courseID), userID, isAdmin, &req)
	if err != nil {
		if bizErr, ok := err.(*errcode.BusinessError); ok {
			response.ErrorWithBusiness(c, bizErr)
			return
		}
		response.Error(c, 500, err.Error())
		return
	}

	page := req.Page
	if page < 1 {
		page = 1
	}
	pageSize := req.PageSize
	if pageSize < 1 {
		pageSize = 10
	}

	response.SuccessWithPage(c, items, total, page, pageSize, "获取成功")
}

// AdminList 管理员查看所有预约
func (h *BookingHandler) AdminList(c *gin.Context) {
	var req model.BookingListReq
	if err := c.ShouldBindQuery(&req); err != nil {
		response.Error(c, 400, "参数错误: "+err.Error())
		return
	}

	items, total, err := h.service.AdminList(&req)
	if err != nil {
		response.Error(c, 500, err.Error())
		return
	}

	page := req.Page
	if page < 1 {
		page = 1
	}
	pageSize := req.PageSize
	if pageSize < 1 {
		pageSize = 10
	}

	response.SuccessWithPage(c, items, total, page, pageSize, "获取成功")
}

// AdminCancel 管理员取消预约
func (h *BookingHandler) AdminCancel(c *gin.Context) {
	bookingID, err := strconv.ParseUint(c.Param("id"), 10, 32)
	if err != nil {
		response.Error(c, 400, "预约ID格式错误")
		return
	}

	var req model.BookingCancelReq
	if err := c.ShouldBindJSON(&req); err != nil {
		response.Error(c, 400, "参数错误: "+err.Error())
		return
	}

	adminID := c.GetUint("userID")

	if err := h.service.AdminCancel(uint(bookingID), &req, adminID); err != nil {
		if bizErr, ok := err.(*errcode.BusinessError); ok {
			response.ErrorWithBusiness(c, bizErr)
			return
		}
		response.Error(c, 500, err.Error())
		return
	}

	response.Success(c, nil, "取消成功")
}
